/*
 * psthread.cpp
 *
 *  Created on: 2011-4-27
 *      Author: chenl
 */

#include "psthread.h"
#include "logengine/buffedlog.h"
#include "common/common_def.h"
#include "common/common_err.h"
#include "config.h"
#include "task_wrapper.h"
#include "psapp.h"

#define DEFAULT_PSTHREAD_LOGPREFIX "./log/ps_main"

CPSThread::CPSThread()
	: logEngine(GET_PSTHREADLOG_INSTANCE())
{

}
CPSThread::~CPSThread()
{

}


int32_t CPSThread::Initialize()
{
	logEngine.SetParam(GET_PARAMCONFIG_INSTANCE().GetLogLevel(), DEFAULT_PSTHREAD_LOGPREFIX, &GET_LOGQUEUE_INSTANCE());
	int32_t ret = logEngine.Initialize();
	if (0 > ret)
	{
		return ret;
	}

	//初始化調度應用層
	ret = CREATE_PSAPP_INSTANCE().Initialize();
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Initializing PSAPP failed! ret=0x%08x", ret);
		return ret;
	}

	const CParamConfig& config = GET_PARAMCONFIG_INSTANCE();
	CTimerMgt& timerMgt = GET_TIMERMGT_INSTANCE();

	//心跳定時器
	int64_t heartBeatPeriod = (int64_t)US_PER_SECOND * config.GetSlowerTimes() / config.GetHZ();
	CTimerMgt::TimerID timerID = enmInvalidTimerID;
	timerID = timerMgt.SetTimer(enmTimerType_HeartBeat, this->thread_,
			heartBeatPeriod, true, 0, 0);
	if (enmInvalidTimerID == timerID)
	{
		return E_UNKNOWN;
	}
	return S_OK;
}

int32_t CPSThread::Uninitialize()
{
	//銷毀調度應用層
	int32_t ret = CREATE_PSAPP_INSTANCE().Uninitialize();
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "Uninitializing PSAPP failed! ret=0x%08x", ret);
		return ret;
	}
	return S_OK;
}

void CPSThread::Execute()
{
	bool bIdle = true;
	bool bNeedReDraw = true;
	CPSApp& psApp = GET_PSAPP_INSTANCE();

	while((!IsTerminated()) || (!bIdle))
	{
		bIdle = true;

		//是否需要重畵
		bNeedReDraw = psApp.IsModified();
		if (bNeedReDraw)
		{
			DELAY(enmDefaultThreadExecutePeriod);
		}
		//已重畵
		if (psApp.IsUpdated())
		{
			bNeedReDraw = false;
		}
		//處理定時器
		if (ProcessTimer())
		{
			psApp.SetModified();
			bIdle = false;
		}

		if (bIdle || bNeedReDraw)
		{
			DELAY(enmDefaultThreadExecutePeriod);
		}

	}
}


bool CPSThread::ProcessTimer()
{
	CTimerMgt& timerMgt = GET_TIMERMGT_INSTANCE();
	CTimerMgt::TimerID timerID = timerMgt.GetFirstTimer();
	if (enmInvalidTimerID == timerID)
	{
		logEngine.WriteLog(enmLogLevel_DEBUG, "No Timer in timerMgt");
		return false;
	}
	Timer timer = {0};
	int32_t ret = timerMgt.GetTimer(timerID, timer);
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "GetTimer(timerID=%d,timerType=%d) failed! ret=0x%08x", timerID,  timer.enmTimerType, ret);
		return false;
	}
	if (!IsTimerFire(timer))
		return false;

	OnTimer(timerID, timer);
	return true;
}

void CPSThread::OnTimer(CTimerMgt::TimerID timerID, Timer& timer)
{
	int32_t ret = S_OK;
	CTimerMgt& timerMgt = GET_TIMERMGT_INSTANCE();

	switch(timer.enmTimerType)
	{
	case enmTimerType_HeartBeat:
		logEngine.WriteLog(enmLogLevel_DEBUG, "find timerID=%d timertype=%d(enmTimerType_HeartBeat)", timerID, timer.enmTimerType);
		//更新task時間
		GET_PSAPP_INSTANCE().UpDateTaskTimes();
		//調度
		GET_PSAPP_INSTANCE().DoSchedule();
		break;
	default:
		logEngine.WriteLog(enmLogLevel_DEBUG, "find timerID=%d but timerType=%d", timerID, timer.enmTimerType);
	}
	ret = timerMgt.TimerFired(timerID);
	if (0 > ret)
	{
		logEngine.WriteLog(enmLogLevel_ERROR, "TimerFired(timerID=%d,timerType=%d) failed! ret=0x%08x", timerID,  timer.enmTimerType, ret);
	}
}
